package cn.casc.tools.maven;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.CompletableFuture;
import java.util.jar.JarFile;
import java.util.logging.Logger;

/**
 * @author max
 * @version 1.0.1
 * @className UploaderFrame
 * @description
 * @copyright Copyright (c) 2023
 * @company 天纲梦工厂
 * @datetime 2024/7/18 13:55
 **/

public class UploaderFrame extends JFrame {
    final static Logger LOGGER = Logger.getLogger(UploaderFrame.class.getName());

    JTextField tfFilePath;
    JList<FileItem> lFiles;
    JButton btnUpload;

    volatile boolean killed = false;

    public UploaderFrame() {
        JFrame frame = this;
        frame.setTitle("内部工具");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(200,100);
        frame.setSize(600,400);
        frame.setLayout(new BorderLayout());
        {
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            frame.add(panel, BorderLayout.NORTH);


            JButton btFilePath = new JButton("文件路径: ");
            panel.add(btFilePath, BorderLayout.WEST);

            btFilePath.addActionListener((evt) -> {
                File dir = new File(this.tfFilePath.getText());
                JFileChooser chooser = null;
                if(dir.exists()) {
                    if(dir.isDirectory()) {
                        chooser = new JFileChooser(dir);
                    }else if(dir.isFile()) {
                        chooser = new JFileChooser(dir.getParentFile().getPath());
                    }
                } else {
                    chooser = new JFileChooser();
                }
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                chooser.showOpenDialog(frame);
                File file = chooser.getSelectedFile();
                if(file != null) {
                    FileItem[] fileItems = FileItem.getFileItemArray(file.getPath());
                    this.lFiles.setListData(fileItems);
                }
            });

            JButton btnSettings = new JButton("配置");
            panel.add(btnSettings, BorderLayout.EAST);

            btnSettings.addActionListener((evt) -> {
                ConfigDialog.INSTANCE.show();
            });

            this.tfFilePath = new JTextField();
            this.tfFilePath.addActionListener((evt) -> this.onOpenFile());
            this.lFiles = new JList<>();
            FileItem[] fileItems = FileItem.getFileItemArray(Config.get().lastOpenDir);
            this.lFiles.setListData(fileItems);
            tfFilePath.setColumns(60);
            tfFilePath.setText(Config.get().lastOpenDir);

            panel.add(tfFilePath, BorderLayout.CENTER);
            this.lFiles.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    super.mouseClicked(e);
                    if(e.getClickCount() == 2) {
                        onEnterFile();
                    }
                }
            });

        }

        {
            JPanel panel = new JPanel();
            panel.setLayout(new FlowLayout());
            frame.add(panel, BorderLayout.SOUTH);

            this.btnUpload = new JButton("上传至maven仓库");

            this.btnUpload.addActionListener((evt) -> {
                onUpload();
            });
            panel.add(this.btnUpload);
        }

        JScrollPane scrollPane = new JScrollPane(this.lFiles);
        frame.add(scrollPane, BorderLayout.CENTER);

        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
                killed = true;
                onClose();
                super.windowClosing(we);
            }
        });
    }

    public void onClose() {
        Config.get().save();
    }

    public void onOpenFile() {
        String path = this.tfFilePath.getText();
        System.out.println(path);

        File file = new File(path);
        if(file.exists()) {
            enterFile(new FileItem(file, file.getName()));
        } else  {
            JOptionPane.showMessageDialog(this, "文件路径不存在");
        }
    }

    public void enterFile(FileItem selected) {
        if(selected.file.isDirectory()) {
            this.lFiles.setListData(FileItem.getFileItemArray(selected.file.getPath()));
        } else if(selected.file.isFile()) {
            if(selected.name.endsWith(".zip")) {
                this.lFiles.setListData(FileItem.unzip(selected.file));
            }
        }
        String path = selected.file.getAbsolutePath();
        Config.get().lastOpenDir = path;
        this.tfFilePath.setText(path);

    }

    public void onEnterFile() {
        FileItem selected = this.lFiles.getSelectedValue();
        if(selected != null) {
            enterFile(selected);
        }
    }

    public void onUpload() {
        final FileItem selected = this.lFiles.getSelectedValue();
        if(selected == null) {
            JOptionPane.showMessageDialog(this, "至少要选择一个文件");
            return;
        }
        if(selected.file.isFile()) {
            if(selected.file.getName().endsWith(".zip") && selected.name.endsWith(".jar")) {
                this.btnUpload.setEnabled(false);
                uploadZipJar(selected);
                this.btnUpload.setEnabled(true);

            } else if(selected.file.getName().endsWith(".jar")) {
                this.btnUpload.setEnabled(false);
                uploadJar(selected);
                this.btnUpload.setEnabled(true);
            } else  {
                JOptionPane.showMessageDialog(this, "只支持jar个文件");
            }
        } else if(selected.file.isDirectory()) {
            uploadDir(selected);
        } else {
            JOptionPane.showMessageDialog(this, "只支持jar个文件");
        }
    }

    public void uploadZipJar(FileItem selected) {
        try {
            Path dir = Files.createTempDirectory("er-tools");

            ZipFile zipFile = new ZipFile(selected.file);
            do {
                try {
                    zipFile.extractFile(selected.name, dir.toString());
                    break;
                } catch (Exception e) {
                    String password = JOptionPane.showInputDialog("输入密码: ", Config.get().zipPassword);
                    if("".equals(password)) {
                        return;
                    } else {
                        Config.get().zipPassword = password;
                        try {
                            zipFile.setPassword(password);
                        } catch (Exception e2) {
                            e2.printStackTrace();
                        }
                    }
                }
            } while (true);
            JarFile jarFile = new JarFile(dir.toString() + File.separator + selected.name);
            String error = JarUploader.upload(jarFile);
            if(error == null)  {
                JOptionPane.showConfirmDialog(null, "maven上传成功", "maven上传",
                        JOptionPane.CLOSED_OPTION);
            }else {
                JOptionPane.showConfirmDialog(null, error, "上传异常",
                        JOptionPane.CLOSED_OPTION);
            }

        } catch (IOException e) {
            JOptionPane.showConfirmDialog(null, e.getMessage(), "临时目录创建异常", JOptionPane.CLOSED_OPTION);
        } catch (ZipException e) {
            JOptionPane.showConfirmDialog(null, e.getMessage(), "jar包解析异常", JOptionPane.CLOSED_OPTION);
        }
    }

    public void uploadJar(FileItem selected) {
        try {
            JarFile jarFile = new JarFile(selected.file);
            String error = JarUploader.upload(jarFile);
            if(error == JarUploader.JAR_ERROR) {
                String pomInfo = JOptionPane.showInputDialog("请输入maven信息", "<groupId>:<artifactId>:<version>");
                error = JarUploader.uploadWithInfo(jarFile, pomInfo);
            }
            if(error == null) {
                JOptionPane.showMessageDialog(this, "上传成功", "上成功", JOptionPane.INFORMATION_MESSAGE);
            } else  {
                JOptionPane.showMessageDialog(this, error, "上传失败", JOptionPane.ERROR_MESSAGE);
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "jar文件格式不正确");
        }
    }

    public void uploadDir(final FileItem selected) {
        int opt = JOptionPane.showConfirmDialog(this, "确认递归上传目录中的jar文件","上传确认", JOptionPane.OK_CANCEL_OPTION);
        if(opt == JOptionPane.OK_OPTION) {
            this.btnUpload.setEnabled(false);
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                upload(selected.file);
                this.btnUpload.setEnabled(true);
            });
        }
    }

    public void upload(File file) {
        if(file.isDirectory()) {
            for(File sub:file.listFiles()) {
                if(killed == true) {
                    return;
                }
                upload(sub);
            }
        } else if(file.isFile() && file.getName().endsWith(".jar")) {
            try {
                JarFile jarFile = new JarFile(file);
                String error = JarUploader.upload(jarFile);
                if(error != null) {
                    LOGGER.fine(file.getAbsolutePath() +" =>" + error);
                }
            } catch (Exception e) {
                LOGGER.fine(file.getAbsolutePath() +" =>" + e.getMessage());
            }
        }
    }

}